// ----------------------------------------------------------
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v.2.0. If a copy of the MPL
// was not distributed with this file, You can obtain one
// at http://mozilla.org/MPL/2.0/.
// ----------------------------------------------------------
// Codebase: https://github.com/ArKuznetsov/cpdb/
// ----------------------------------------------------------

#Использовать yadisk
#Использовать fs
#Использовать 1commands

Перем Лог;           // - Объект    - объект записи лога приложения

#Область ПрограммныйИнтерфейс

// Процедура, выполняет копирование/перемещение указанных файлов с использованием команд системы (xcopy)
//
// Параметры:
//   Источник           - Строка       - копируемые файлы
//   Приемник           - Строка       - назначение копирования, каталог или файл
//   Перемещение        - Булево       - выполнить перемещение файлов (удалить источник после копирования)
//   ТолькоСегодня      - Булево       - копирование файлов, измененных не ранее текущей даты (параметр /D для xcopy)
//
Процедура КомандаСистемыКопироватьФайл(Знач Источник,
                                       Знач Приемник,
                                       Перемещение = Ложь,
                                       ТолькоСегодня = Ложь) Экспорт

	Источник = ФС.ПолныйПуть(Источник);
	Приемник = ФС.ПолныйПуть(Приемник);
	
	ВремФайл = Новый Файл(Приемник);

	Лог.Информация("Начало копирования файла ""%1"" -> ""%2""", Источник, Приемник);

	Если НЕ ВремФайл.Существует() Тогда
		ФС.ОбеспечитьКаталог(Приемник);
	КонецЕсли;
	Если НЕ ВремФайл.ЭтоКаталог() Тогда
		Лог.Ошибка("Необходимо указать каталог в качестве приемника ""%1""", Приемник);
	КонецЕсли;

	КомандаРК = Новый Команда;
	
	КомандаРК.УстановитьКоманду("xcopy");
	КомандаРК.ДобавитьПараметр(КомандаРК.ОбернутьВКавычки(Источник));
	КомандаРК.ДобавитьПараметр(КомандаРК.ОбернутьВКавычки(Приемник));
	КомандаРК.ДобавитьПараметр("/F");
	КомандаРК.ДобавитьПараметр("/J");
	КомандаРК.ДобавитьПараметр("/V");
	КомандаРК.ДобавитьПараметр("/Y");
	КомандаРК.ДобавитьПараметр("/Z");
	Если ТолькоСегодня Тогда
		ТекДата = ТекущаяДата();
		ФорматированнаяДата = Строка(Формат(ТекДата, "ДФ=MM-dd-yyyy"));
		КомандаРК.ДобавитьПараметр("/D:" + ФорматированнаяДата);
	КонецЕсли;

	КомандаРК.УстановитьИсполнениеЧерезКомандыСистемы(Ложь);
	КомандаРК.ПоказыватьВыводНемедленно(Ложь);
	
	КодВозврата = КомандаРК.Исполнить();

	ОписаниеРезультата = КомандаРК.ПолучитьВывод();
	
	Если КодВозврата = 0 Тогда
		Лог.Информация("Скопирован файл ""%1"" -> ""%2""", Источник, Приемник);
	Иначе
		ТекстОшибки = СтрШаблон("Ошибка копирования файла ""%1"" -> ""%2"", код возврата %3:%4%5",
		                        Источник,
		                        Приемник,
		                        КодВозврата,
		                        Символы.ПС,
		                        ОписаниеРезультата);
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;

	Если Перемещение Тогда
		КомандаСистемыУдалитьФайл(Источник);
	КонецЕсли;

КонецПроцедуры // КомандаСистемыКопироватьФайл()

// Функция, выполняет удаление указанных файлов с использованием команды системы (del)
//
// Параметры:
//   ПутьКФайлу             - Строка         - путь к удаляемому файлу
//   ИсключениеПриОшибке    - Булево         - Истина - вызывать исключение при ошибке удаления
//
Процедура КомандаСистемыУдалитьФайл(Знач ПутьКФайлу, ИсключениеПриОшибке = Ложь) Экспорт

	ПутьКФайлу = ФС.ПолныйПуть(ПутьКФайлу);
	
	Лог.Информация("Начало удаления файла ""%1""", ПутьКФайлу);

	КомандаРК = Новый Команда;

	КомандаРК.УстановитьКоманду(СтрШаблон("IF EXIST %1 del /F /Q %1", КомандаРК.ОбернутьВКавычки(ПутьКФайлу)));

	КомандаРК.УстановитьИсполнениеЧерезКомандыСистемы(Ложь);
	КомандаРК.ПоказыватьВыводНемедленно(Ложь);

	КодВозврата = КомандаРК.Исполнить();

	ОписаниеРезультата = КомандаРК.ПолучитьВывод();
	
	Если Не ПустаяСтрока(ОписаниеРезультата) Тогда
		Лог.Отладка("Вывод команды удаления: " + ОписаниеРезультата);
	КонецЕсли;

	Если КодВозврата = 0 Тогда
		Лог.Информация("Удален файл ""%1""", ПутьКФайлу);
	Иначе
		ТекстОшибки = СтрШаблон("Ошибка удаления файла ""%1"", код возврата %2: %3%4",
		                        ПутьКФайлу,
		                        КодВозврата,
		                        Символы.ПС,
		                        ОписаниеРезультата);
		Если ИсключениеПриОшибке Тогда
			ВызватьИсключение ТекстОшибки;
		Иначе
			Лог.Ошибка(ТекстОшибки);
		КонецЕсли;
	КонецЕсли;

КонецПроцедуры // КомандаСистемыУдалитьФайл()

// Функция читает список файлов из файла
//
// Параметры:
//   ПутьКСписку                    - Строка    - путь к файлу со списком файлов архива
//   ДобавитьПутьКИсходномуФайлу    - Булево    - Истина - при чтении добавлять к результату
//                                                путь к исходному файлу списка
//   ДобавитьИсходныйФайл           - Булево    - Истина - добавить исходный файл в список
//
// Возвращаемое значение:
//   Массив из Строка    - прочитанный список файлов
//
Функция ПрочитатьСписокФайлов(Знач ПутьКСписку, ДобавитьПутьКИсходномуФайлу = Ложь, ДобавитьИсходныйФайл = Ложь) Экспорт

	ПутьКСписку = ФС.ПолныйПуть(ПутьКСписку);

	ДанныеИсхФайла = Новый Файл(ПутьКСписку);

	МассивФайловЧастей = Новый Массив();
	
	ЧтениеСписка = Новый ЧтениеТекста(ПутьКСписку, КодировкаТекста.UTF8);
	СтрокаСписка = ЧтениеСписка.ПрочитатьСтроку();
	Пока СтрокаСписка <> Неопределено Цикл
		Если ЗначениеЗаполнено(СтрокаСписка) Тогда
			ИмяФайла = ИмяФайлаИзСтрокиСписка(СокрЛП(СтрокаСписка));
			Если ДобавитьПутьКИсходномуФайлу Тогда
				МассивФайловЧастей.Добавить(ОбъединитьПути(ДанныеИсхФайла.Путь, ИмяФайла));
			Иначе
				МассивФайловЧастей.Добавить(ИмяФайла);
			КонецЕсли;
		КонецЕсли;
		
		СтрокаСписка = ЧтениеСписка.ПрочитатьСтроку();
	КонецЦикла;
		
	ЧтениеСписка.Закрыть();

	Если ДобавитьИсходныйФайл Тогда
		МассивФайловЧастей.Добавить(?(ДобавитьПутьКИсходномуФайлу, ДанныеИсхФайла.ПолноеИмя, ДанныеИсхФайла.Имя));
	КонецЕсли;

	Возврат МассивФайловЧастей;

КонецФункции // ПрочитатьСписокФайлов()

// Выполняет архиваци указанного файла с разбитием на части указанного размера
//
// Параметры:
//   ПутьКФайлу          - Строка    - путь к файлу, который будет архивироваться
//   ИмяАрхива           - Строка    - имя файла-архива
//   ИмяСпискаФайлов     - Строка    - имя файла-списка (содержащего все чати архива)
//   РазмерТома          - Строка    - размер части {<g>, <m>, <b>} (по умолчанию 50m)
//   СтепеньСжатия       - Число     - уровень сжатия частей архива {0 - 9} (по умолчанию 0 - не сжимать)
//   УдалитьИсточник     - Булево    - Истина - после архивации исходный файл будет удален
//
Процедура ЗапаковатьВАрхив(Знач ПутьКФайлу,
                           Знач ИмяАрхива = Неопределено,
                           Знач ИмяСпискаФайлов = Неопределено,
                           Знач РазмерТома = Неопределено,
                           Знач СтепеньСжатия = 0,
                           Знач УдалитьИсточник = Ложь) Экспорт

	ПутьКФайлу = ФС.ПолныйПуть(ПутьКФайлу);

	ПутьКАрхиватору = НайтиАрхиватор();
	
	Если НЕ ЗначениеЗаполнено(ПутьКАрхиватору) Тогда
		ТекстОшибки = СтрШаблон("Ошибка архивации файла ""%1"": архиватор (7-Zip) не найден",
		                        ПутьКФайлу);
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;

	ДанныеИсхФайла = Новый Файл(ПутьКФайлу);

	Если ЗначениеЗаполнено(ИмяАрхива) Тогда
		ПутьКАрхиву = ИмяАрхива;
	Иначе
		ПутьКАрхиву = ОбъединитьПути(ДанныеИсхФайла.Путь, ДанныеИсхФайла.ИмяБезРасширения + ".7z");
	КонецЕсли;

	ПутьКАрхиву = ФС.ПолныйПуть(ПутьКАрхиву);

	Если НЕ ЗначениеЗаполнено(ИмяСпискаФайлов) Тогда
		ИмяСпискаФайлов = ОбъединитьПути(ДанныеИсхФайла.Путь, ДанныеИсхФайла.ИмяБезРасширения + ".split");
	КонецЕсли;

	Лог.Информация("Начало разбиения файла ""%1"" на части по %2", ПутьКФайлу, РазмерТома);

	КомандаРК = Новый Команда();
	
	КомандаРК.УстановитьКоманду(ПутьКАрхиватору);
	КомандаРК.ДобавитьПараметр("a");
	КомандаРК.ДобавитьПараметр(КомандаРК.ОбернутьВКавычки(ПутьКАрхиву));
	КомандаРК.ДобавитьПараметр(КомандаРК.ОбернутьВКавычки(ПутьКФайлу));
	КомандаРК.ДобавитьПараметр("-t7z");

	Если НЕ ЗначениеЗаполнено(РазмерТома) Тогда
		РазмерТома = "50m";
	КонецЕсли;
	КомандаРК.ДобавитьПараметр(СтрШаблон("-v%1", РазмерТома));

	Если НЕ ЗначениеЗаполнено(СтепеньСжатия) Тогда
		СтепеньСжатия = "0";
	КонецЕсли;
	КомандаРК.ДобавитьПараметр(СтрШаблон("-mx%1", СтепеньСжатия));

	КомандаРК.УстановитьИсполнениеЧерезКомандыСистемы(Ложь);
	КомандаРК.ПоказыватьВыводНемедленно(Ложь);
	
	КодВозврата = КомандаРК.Исполнить();

	ОписаниеРезультата = КомандаРК.ПолучитьВывод();

	Если КодВозврата = 0 Тогда
		КоличествоЧастей = СоздатьСписокФайлов(ПутьКАрхиву, ИмяСпискаФайлов);
		Лог.Информация("Выполнено разбиение файла ""%1"" на %2 частей по %3", ПутьКФайлу, КоличествоЧастей, РазмерТома);
	Иначе
		ТекстОшибки = СтрШаблон("Ошибка разбиения файла ""%1"", код возврата %2:%3%4",
		                        ПутьКФайлу,
		                        КодВозврата,
		                        Символы.ПС,
		                        ОписаниеРезультата);
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;

	Если УдалитьИсточник Тогда
		КомандаСистемыУдалитьФайл(ПутьКФайлу);
	КонецЕсли;

КонецПроцедуры // ЗапаковатьВАрхив()

// Процедура, выполняет распаковку архива
//
// Параметры:
//   ПутьКАрхиву         - Строка    - путь к файлу архива, который будет распаковываться
//   ЭтоСписокФайлов     - Булево    - Истина - передан список файлов;
//                                     Ложь - передан первый том архива
//   УдалитьИсточник     - Булево    - Истина - после распаковки исходный файл будет удален
//
Процедура РаспаковатьАрхив(Знач ПутьКАрхиву, Знач ЭтоСписокФайлов = Ложь, Знач УдалитьИсточник = Ложь) Экспорт

	ПутьКАрхиву = ФС.ПолныйПуть(ПутьКАрхиву);

	ПутьКАрхиватору = НайтиАрхиватор();

	Если НЕ ЗначениеЗаполнено(ПутьКАрхиватору) Тогда
		ТекстОшибки = СтрШаблон("Ошибка распаковки архива ""%1"": архиватор (7-Zip) не найден",
		                        ПутьКАрхиву);
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;

	ДанныеИсхФайла = Новый Файл(ПутьКАрхиву);

	МассивФайловЧастей = Новый Массив();

	Если ЭтоСписокФайлов Тогда
		МассивФайловЧастей = ПрочитатьСписокФайлов(ПутьКАрхиву, Истина, Истина);
		ПерваяЧастьАрхива = МассивФайловЧастей[0];
	Иначе
		ПерваяЧастьАрхива = ПутьКАрхиву;
		МассивФайловЧастей = НайтиФайлы(ДанныеИсхФайла.Путь, ДанныеИсхФайла.ИмяБезРасширения + ".???", Ложь);
	КонецЕсли;

	Лог.Отладка("Всего частей: " + МассивФайловЧастей.Количество());

	Лог.Информация("Начало распаковки из архива ""%1""", ПерваяЧастьАрхива);

	КомандаРК = Новый Команда();
	
	КомандаРК.УстановитьКоманду(ПутьКАрхиватору);
	КомандаРК.ДобавитьПараметр("x");
	КомандаРК.ДобавитьПараметр("-aoa");
	КомандаРК.ДобавитьПараметр("-y");
	КомандаРК.ДобавитьПараметр(СтрШаблон("-o%1", ДанныеИсхФайла.Путь));
	КомандаРК.ДобавитьПараметр(ПерваяЧастьАрхива);

	КомандаРК.УстановитьИсполнениеЧерезКомандыСистемы(Ложь);
	КомандаРК.ПоказыватьВыводНемедленно(Ложь);
	
	КодВозврата = КомандаРК.Исполнить();

	ОписаниеРезультата = КомандаРК.ПолучитьВывод();

	Если КодВозврата = 0 Тогда
		Если УдалитьИсточник Тогда
			Для Каждого ФайлЧасти Из МассивФайловЧастей Цикл
				Если ТипЗнч(ФайлЧасти) = Тип("Файл") Тогда
					УдалитьФайлы(ФайлЧасти.ПолноеИмя);
				Иначе
					УдалитьФайлы(ФайлЧасти);
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
		Лог.Информация("Распакован архив ""%1""", ПерваяЧастьАрхива);
	Иначе
		ТекстОшибки = СтрШаблон("Ошибка распаковки архива ""%1"", код возврата %2:%3%4",
		                        ПерваяЧастьАрхива,
		                        КодВозврата,
		                        Символы.ПС,
		                        ОписаниеРезультата);
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;

КонецПроцедуры // РаспаковатьАрхив()

// Процедура подключает указанный сетевой диск
//
// Параметры:
//   ИмяУстройства         - Строка    - имя (буква) подключаемого диска
//   ИмяРесурса            - Строка    - сетевой путь к подключаемому ресурсу
//   Пользователь          - Строка    - пользователь от имени которого выполняется подключение
//   ПарольПользователя    - Строка    - пароль пользователя от имени которого выполняется подключение
//
Процедура ПодключитьДиск(ИмяУстройства, ИмяРесурса, Пользователь, ПарольПользователя) Экспорт

	Лог.Информация("Начало подключения сетевого ресурса ""%1"" к устройству ""%2""",
	               ИмяРесурса,
	               ИмяУстройства);

	КомандаРК = Новый Команда;
	
	КомандаРК.УстановитьКоманду("net");
	КомандаРК.ДобавитьПараметр("use");
	КомандаРК.ДобавитьПараметр(ИмяУстройства);
	КомандаРК.ДобавитьПараметр(ИмяРесурса);
	КомандаРК.ДобавитьПараметр("/USER:" + Пользователь);
	КомандаРК.ДобавитьПараметр(ПарольПользователя);

	КомандаРК.УстановитьИсполнениеЧерезКомандыСистемы( Ложь );
	КомандаРК.ПоказыватьВыводНемедленно( Ложь );
	
	КодВозврата = КомандаРК.Исполнить();

	ОписаниеРезультата = КомандаРК.ПолучитьВывод();
	
	Если НЕ КодВозврата = 0 Тогда
		ВызватьИсключение СтрШаблон("Ошибка ошибка подключения ресурса ""%1"" к устройству ""%2"", код ошибки %3: %4%5",
		                            ИмяРесурса,
		                            ИмяУстройства,
		                            КодВозврата,
		                            Символы.ПС,
		                            ОписаниеРезультата);
	КонецЕсли;
	
	Лог.Информация("Подключен сетевой ресурс ""%1"" к устройству ""%2"": %3",
	               ИмяРесурса,
	               ИмяУстройства,
	               ОписаниеРезультата);

КонецПроцедуры // ПодключитьДиск()

// Процедура отключает указанный сетевой диск
//
// Параметры:
//   ИмяУстройства    - Строка    - имя (буква) отключаемого диска
//
Процедура ОтключитьДиск(ИмяУстройства) Экспорт

	Лог.Информация("Начало отключения устройства ""%1""", ИмяУстройства);

	КомандаРК = Новый Команда;
	
	КомандаРК.УстановитьКоманду("net");
	КомандаРК.ДобавитьПараметр("use");
	КомандаРК.ДобавитьПараметр(ИмяУстройства);
	КомандаРК.ДобавитьПараметр("/DELETE");

	КомандаРК.УстановитьИсполнениеЧерезКомандыСистемы( Ложь );
	КомандаРК.ПоказыватьВыводНемедленно( Ложь );
	
	КодВозврата = КомандаРК.Исполнить();

	ОписаниеРезультата = КомандаРК.ПолучитьВывод();
	
	Если НЕ КодВозврата = 0 Тогда
		ВызватьИсключение СтрШаблон("Ошибка ошибка отключения устройства ""%1"", код ошибки %2: %3%4",
		                            ИмяУстройства,
		                            КодВозврата,
		                            Символы.ПС,
		                            ОписаниеРезультата);
	КонецЕсли;

	Лог.Информация("Отключено устройство ""%1"": %2",
	               ИмяУстройства,
	               ОписаниеРезультата);

КонецПроцедуры // ОтключитьДиск()

#КонецОбласти // ПрограммныйИнтерфейс

#Область СлужебныйПрограммныйИнтерфейс

// Функция - разбивает переданный путь к файлу на части
//
// Параметры:
//   ПутьКФайлу    - Строка    - путь к файлу/каталогу
//
// Возвращаемое значение:
//   Структура    - части пути к файлу
//     *Имя           - Строка    - имя файла/каталога
//     *Путь          - Строка    - путь к каталогу в котором расположен файл/каталог
//     *ПолныйПуть    - Строка    - полный путь к файлу/каталогу
//
Функция ЧастиПути(Знач ПутьКФайлу) Экспорт

	Результат = Новый Структура();
	
	ПутьКФайлу = СтрЗаменить(ПутьКФайлу, "\", "/");

	Результат.Вставить("ПолныйПуть", ПутьКФайлу);

	ЧастиПути = СтрРазделить(ПутьКФайлу, "/", Ложь);
	
	Результат.Вставить("Имя", ЧастиПути[ЧастиПути.ВГраница()]);

	ЧастиПути.Удалить(ЧастиПути.ВГраница());

	Результат.Вставить("Путь", СтрСоединить(ЧастиПути, "/"));

	Возврат Результат;

КонецФункции // ЧастиПути()

#КонецОбласти // ПрограммныйИнтерфейс

#Область СлужебныеПроцедурыИФункции

// Функция - ищет и возвращает путь к архиватору 7-zip с использованием команды where/whereis
//
// Возвращаемое значение:
//  Строка   - путь к исполняемому файлу архиватора 7-zip
//
Функция НайтиАрхиваторКомандойПоиска()

	ЭтоWindows = ПараметрыСистемы.ЭтоWindows();
	НайденныйПуть = Неопределено;

	Команда = Новый Команда();

	Если ЭтоWindows Тогда
		Команда.УстановитьКоманду("where");
	Иначе
		Команда.УстановитьКоманду("whereis");
	КонецЕсли;
	Команда.ДобавитьПараметр("7z");

	КодВозврата = Команда.Исполнить();
	ВыводКоманды = Команда.ПолучитьВывод();

	Если КодВозврата = 0 Тогда
		НайденныйПуть = ВыводКоманды;
		Если НЕ ЭтоWindows Тогда
			НайденныйПуть = СтрЗаменить(НайденныйПуть, "7z:", ""); 
			ЧастиСтроки = СтрРазделить(СокрЛП(НайденныйПуть), " ");
			НайденныйПуть = ЧастиСтроки[0];

			Если ПустаяСтрока(НайденныйПуть) Тогда
				НайденныйПуть = Неопределено;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;

	Возврат НайденныйПуть;

КонецФункции // НайтиАрхиваторКомандойПоиска()

// Функция - ищет и возвращает путь к архиватору 7-zip в стандартных каталогах установки программ
//
// Возвращаемое значение:
//  Строка   - путь к исполняемому файлу архиватора 7-zip
//
Функция НайтиАрхиваторВКаталогахПрограмм()

	КаталогиПрограмм = Новый Массив();

	Если ПараметрыСистемы.ЭтоWindows() Тогда
		КаталогиПрограмм.Добавить(ПолучитьПеременнуюСреды("ProgramFiles"));
		КаталогиПрограмм.Добавить(ПолучитьПеременнуюСреды("ProgramFiles(x86)"));
		ИмяИсполняемогоФайла = "7z.exe";
	Иначе
		КаталогиПрограмм.Добавить(ОбъединитьПути("", "usr", "bin"));
		КаталогиПрограмм.Добавить(ОбъединитьПути("", "usr", "local", "bin"));
		ИмяИсполняемогоФайла = "7z";
	КонецЕсли;

	НайденныйПуть = Неопределено;

	Для Каждого ТекКаталог Из КаталогиПрограмм Цикл
		Массив7ZIP = НайтиФайлы(ТекКаталог, ИмяИсполняемогоФайла, True);
		Если ЗначениеЗаполнено(Массив7ZIP) Тогда
			НайденныйПуть = Массив7ZIP[0].ПолноеИмя;
			Прервать;
		КонецЕсли;
	КонецЦикла;

	Возврат НайденныйПуть;

КонецФункции // НайтиАрхиваторВКаталогахПрограмм()

// Функция - ищет и возвращает путь к архиватору 7-zip
//
// Возвращаемое значение:
//  Строка   - путь к исполняемому файлу архиватора 7-zip
//
Функция НайтиАрхиватор()

	НайденныйПуть = НайтиАрхиваторКомандойПоиска();

	Если НЕ ЗначениеЗаполнено(НайденныйПуть) Тогда
		НайденныйПуть = НайтиАрхиваторВКаталогахПрограмм();
	КонецЕсли;

	Возврат НайденныйПуть;

КонецФункции // НайтиАрхиватор()

// Функция создает файл-список файлов архива и возвращает количество
//
// Параметры:
//   ПутьКАрхиву         - Строка    - путь к файлу архива
//   ИмяСпискаФайлов     - Строка    - имя файла-списка файлов архива
//
// Возвращаемое значение:
//   Число - количество файлов архива
//
Функция СоздатьСписокФайлов(ПутьКАрхиву, ИмяСпискаФайлов)

	ПутьКАрхиву = ФС.ПолныйПуть(ПутьКАрхиву);

	ВремАрхив = Новый Файл(ПутьКАрхиву);

	МассивФайловЧастей = НайтиФайлы(ВремАрхив.Путь, ВремАрхив.Имя + ".???", Ложь);
	Лог.Отладка("Всего частей: " + МассивФайловЧастей.Количество());

	ЗаписьСписка = Новый ЗаписьТекста(ИмяСпискаФайлов, КодировкаТекста.UTF8, , Ложь);

	РасчетХешей = Новый ХешированиеДанных(ХешФункция.MD5);

	Для каждого ФайлЧасти Из МассивФайловЧастей Цикл
		РасчетХешей.ДобавитьФайл(ФайлЧасти.ПолноеИмя);
		ЗаписьСписка.ЗаписатьСтроку(СтрШаблон("%1 %2", ФайлЧасти.Имя, РасчетХешей.ХешСуммаСтрокой));
		РасчетХешей.Очистить();
	КонецЦикла;
	ЗаписьСписка.Закрыть();

	Возврат МассивФайловЧастей.Количество();

КонецФункции // СоздатьСписокФайлов()

// Функция читает имя файла из строки с именем и хэшем файла
//
// Параметры:
//   СтрокаСписка    - Строка    - строка для чтения
//
// Возвращаемое значение:
//   Строка    - имя файла
//
Функция ИмяФайлаИзСтрокиСписка(Знач СтрокаСписка)

	ДлинаХеша = 32;

	ЧастиСтрокиФайла = СтрРазделить(СтрокаСписка, " ", Ложь);
	ИмяФайла = "";
	Для й = 0 По ЧастиСтрокиФайла.ВГраница() Цикл
		Если й = ЧастиСтрокиФайла.ВГраница() И СтрДлина(ЧастиСтрокиФайла[й]) = ДлинаХеша Тогда
			Прервать;
		КонецЕсли;
		ИмяФайла = ИмяФайла + ЧастиСтрокиФайла[й];
	КонецЦикла;

	Возврат ИмяФайла;

КонецФункции // ИмяФайлаИзСтрокиСписка()

#КонецОбласти // СлужебныеПроцедурыИФункции

Лог = ПараметрыСистемы.Лог();
